﻿using Betalgo.Ranul.OpenAI.Managers;
using Betalgo.Ranul.OpenAI.ObjectModels.RequestModels;
using System.Text;
using static Betalgo.Ranul.OpenAI.ObjectModels.StaticValues.AssistantsStatics.MessageStatics;

namespace Windows_AI_Assistant.Services
{
    public interface IAIService
    {
        Task<string> GetChatCompletionAsync(OpenAIService openAIService, string model, IList<ChatMessage> messages, Action<string> onMessageReceived, Action<string> onCompletionReceived);
    }
    public class AIService : IAIService
    {
        /// <summary>
        /// 标点符号响应内容
        /// </summary>
        private const string punctuationMarks = ",.!?，。！？";

        /// <summary>
        /// 获取聊天完成内容
        /// </summary>
        /// <param name="openAIService">openAI服务</param>
        /// <param name="model">模型名称</param>
        /// <param name="messages">聊天消息列表</param>
        /// <param name="onMessageReceived">聊天消息接收回调</param>
        /// <param name="onCompletionReceived">聊天完成内容接收回调</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="Exception"></exception>
        public async Task<string> GetChatCompletionAsync(OpenAIService openAIService, string model, IList<ChatMessage> messages, Action<string> onMessageReceived, Action<string> onCompletionReceived)
        {
            if (openAIService == null) throw new ArgumentNullException(nameof(openAIService));
            if (model == null) throw new ArgumentNullException(nameof(model));
            if (messages == null) throw new ArgumentNullException(nameof(messages));
            if (onMessageReceived == null) throw new ArgumentNullException(nameof(onMessageReceived));
            if (onCompletionReceived == null) throw new ArgumentNullException(nameof(onCompletionReceived));

            StringBuilder responseBuilder = new StringBuilder();
            string lastSegment = "";

            // 设置一个10秒的超时
            using (var cancellationTokenSource = new CancellationTokenSource(10000))
            {
                try
                {
                    await foreach (var completion in openAIService.ChatCompletion.CreateCompletionAsStream(new ChatCompletionCreateRequest
                    {
                        Model = model,
                        Messages = messages
                    }, cancellationToken: cancellationTokenSource.Token))
                    {
                        if (completion.Successful)
                        {
                            string content = completion.Choices.First().Message.Content;
                            responseBuilder.Append(content);
                            onMessageReceived?.Invoke(responseBuilder.ToString());

                            string currentResponse = responseBuilder.ToString();
                            int lastPunctuationIndex = currentResponse.Length - 1;
                            while (lastPunctuationIndex >= 0 && !punctuationMarks.Contains(currentResponse[lastPunctuationIndex]))
                            {
                                lastPunctuationIndex--;
                            }

                            if (lastPunctuationIndex >= 0)
                            {
                                string segment = currentResponse.Substring(lastSegment.Length, lastPunctuationIndex - lastSegment.Length + 1);
                                if (!string.IsNullOrWhiteSpace(segment))
                                {
                                    onCompletionReceived?.Invoke(segment);
                                }
                                lastSegment = currentResponse.Substring(0, lastPunctuationIndex + 1);
                            }
                        }
                        else
                        {
                            throw new Exception($"API Error: {completion.Error?.Code} - {completion.Error?.Message}");
                        }
                    }
                }
                catch (OperationCanceledException)
                {
                    responseBuilder.Append("等待10秒返回超时。");
                    onMessageReceived?.Invoke(responseBuilder.ToString());
                    // 处理超时情况
                    return responseBuilder.ToString(); // 或者您可以选择抛出一个特定的异常，或返回特定的字符串
                }
            }

            if (responseBuilder.Length > lastSegment.Length)
            {
                string finalSegment = responseBuilder.ToString().Substring(lastSegment.Length);
                onCompletionReceived?.Invoke(finalSegment);
            }
            return responseBuilder.ToString();
        }
    }
}
